﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace Map
{
    public class GeoPoint
    {
        public static readonly GeoPoint Null = new GeoPoint(double.PositiveInfinity, double.PositiveInfinity);
        double lat, lon;

        [XmlAttribute]
        public double Latitude
        {
            get { return lat; }
            set
            {
                if (value >= -90 && value <= 90 || Double.IsInfinity(value))
                    lat = value;
                else throw new FormatException("Invalid latitude value");
            }
        }
        [XmlAttribute]
        public double Longitude
        {
            get { return lon; }
            set
            {
                if (value >= -180 && value <= 180 || Double.IsInfinity(value))
                    lon = value;
                else throw new FormatException("Invalid longitude value");
            }
        }

        public GeoPoint()
        {
            Latitude = Double.PositiveInfinity;
            Longitude = Double.PositiveInfinity;
        }

        public GeoPoint(double lat, double lon) : this()
        {
            Latitude = lat;
            Longitude = lon;
        }

        public override string ToString()
        {
            return string.Format("{0}, {1}", Latitude, Longitude);
        }

        public static bool operator ==(GeoPoint left, GeoPoint right)
        {
            return left.Longitude == right.Longitude && left.Latitude == right.Latitude;
        }

        public static bool operator !=(GeoPoint left, GeoPoint right)
        {
            return left.Longitude != right.Longitude || left.Latitude != right.Latitude;
        }
        public override bool Equals(object obj)
        {
            GeoPoint other = (GeoPoint)obj;
            return this == other;
        }

        public override int GetHashCode()
        {
            return Latitude.GetHashCode() + Longitude.GetHashCode();
        }
    }

    public struct GeoArea
    {
        [XmlAttribute]
        public string Name;
        [XmlElement]
        public GeoPoint UpperLeft;
        [XmlElement]
        public GeoPoint LowerRight;
        public static GeoArea Null = new GeoArea(GeoPoint.Null, GeoPoint.Null);

        public GeoArea(double lat1, double lon1, double lat2, double lon2) : this()
        {
            UpperLeft = new GeoPoint(lat1, lon1);
            LowerRight = new GeoPoint(lat2, lon2);
        }

        public GeoArea(GeoPoint UpperLeft, GeoPoint LowerRight) : this()
        {
            this.UpperLeft = UpperLeft;
            this.LowerRight = LowerRight;
        }
    }

    public class Segment
    {
        public string Text {get; set;}
        public string Distance {get; set;}
        public string Time { get; set; }
        public GeoPoint geoPoint { get; set; }
        public string RoadName { get; set; }
        public string FormattedText { get; set; }
        public string[] Notes { get; set; }
    }

    public class Route
    {
        public GeoPoint[] PolyLine {get; set;}
        public int[] Levels { get; set; }
        public float LineWidth { get; set; }
    }

    public class Directions : Route
    {
        public Segment[] Segments { get; set; }
    }
}
